using System;
using System.ComponentModel;

namespace Deepcode.Flux.Core.UI.Controls.Helpers
{
	/// <summary>
	/// GridPagingController calculates various pieces of information given a 
	/// startrow, rows per page and total records in a query.
	/// </summary>
	public class GridPagingController
	{
		#region Property Containers
		private int _startRow;
		private int _lastRow;
		private int _rowsPerPage;
		private int _currentPage;
		private int _totalPages;
		private int _totalRecords;
		private bool _hasNextButton;
		private bool _hasPrevButton;
		private int _nextPageRowStart;
		private int _prevPageRowStart;
		#endregion
		#region Properties
		public int StartRow{get{return _startRow;} set{ _startRow = value; }}
		public int LastRow{get{return _lastRow;} set{ _lastRow = value; }}
		public int RowsPerPage{get{return _rowsPerPage;} set{ _rowsPerPage = value;}}
		public int CurrentPage{get{return _currentPage;} set{ _currentPage = value;}}
		public int TotalPages{get{return _totalPages;} set{ _totalPages = value;}}
		public int TotalRecords{get{return _totalRecords;} set{ _totalRecords = value;}}
		public bool HasNextButton{get{return _hasNextButton;} set{ _hasNextButton = value;}}
		public bool HasPrevButton{get{return _hasPrevButton;} set{ _hasPrevButton = value;}}
		public int NextPageRowStart{get{return _nextPageRowStart;} set{_nextPageRowStart = value;}}
		public int PrevPageRowStart{get{return _prevPageRowStart;} set{_prevPageRowStart = value;}}
		#endregion

		/// <summary>
		/// Constructor - initialises everything to defaults
		/// </summary>
		public GridPagingController()
		{
			_startRow = 1;
			_lastRow = 1;
			_rowsPerPage = 1;
			_currentPage = 1;
			_totalPages = 1;
			_totalRecords = 1;
			_hasNextButton = false;
			_hasPrevButton = false;
			_nextPageRowStart = 1;
			_prevPageRowStart = 1;
		}
		/// <summary>
		/// Static function to return a paging controller object populated from the
		/// information passed in to it.
		/// </summary>
		/// <param name="startrow"></param>
		/// <param name="rpp"></param>
		/// <param name="totalrecords"></param>
		/// <returns></returns>
		public static GridPagingController GetPagingController(int startrow, int rpp, int totalrecords)
		{
			GridPagingController gpc = new GridPagingController();
			gpc.StartRow = startrow;
			gpc.TotalRecords = totalrecords;
			gpc.RowsPerPage = rpp;

			// Ensure startrow is in scope
			if( gpc.StartRow < 1 ) gpc.StartRow = 1;
			if( gpc.StartRow > gpc.TotalRecords ) gpc.StartRow = gpc.TotalRecords;

			// Ensure start row is on a RPP boundary
			int tempLast = (gpc.StartRow + gpc.RowsPerPage )-1;
			if( (tempLast % gpc.RowsPerPage) != 0 )
				gpc.StartRow = ((Convert.ToInt32(System.Math.Floor((double) tempLast / gpc.RowsPerPage))) * gpc.RowsPerPage) - (gpc.RowsPerPage-1);

			// Calculate number of pages
			gpc.TotalPages = Convert.ToInt32(System.Math.Floor( (double) gpc.TotalRecords/gpc.RowsPerPage ));
			if(( gpc.TotalPages * gpc.RowsPerPage ) < gpc.TotalRecords ) gpc.TotalPages++;

			gpc.LastRow = (gpc.StartRow+gpc.RowsPerPage)-1;
			gpc.CurrentPage = Convert.ToInt32(System.Math.Floor( (double) gpc.LastRow / gpc.RowsPerPage ));
			gpc.HasNextButton = false;
			gpc.HasPrevButton = false;
			gpc.NextPageRowStart = 0;
			gpc.PrevPageRowStart = 0;

			if( gpc.StartRow > 1 )
			{
				gpc.HasPrevButton = true;
				gpc.PrevPageRowStart = gpc.StartRow - gpc.RowsPerPage;
			}
			if( gpc.CurrentPage < gpc.TotalPages )
			{
				gpc.HasNextButton = true;
				gpc.NextPageRowStart = gpc.LastRow + 1;
			}
			if( gpc.LastRow > gpc.TotalRecords ) gpc.LastRow = gpc.TotalRecords;
			return gpc;
		}
		/// <summary>
		/// Utility function to save a paging controller into the viewstate
		/// </summary>
		/// <param name="ViewState"></param>
		public void SaveToViewstate( System.Web.UI.StateBag ViewState )
		{
			ViewState["StartRow"] = _startRow;
			ViewState["LastRow"] = _lastRow;
			ViewState["RowsPerPage"] = _rowsPerPage;
			ViewState["CurrentPage"] = _currentPage;
			ViewState["TotalPages"] = _totalPages;
			ViewState["TotalRecords"] = _totalRecords;
			ViewState["hasNextButton"] = _hasNextButton;
			ViewState["hasPrevButton"] = _hasPrevButton;
			ViewState["nextPageRowStart"] = _nextPageRowStart;
			ViewState["prevPageRowStart"] = _prevPageRowStart;
		}
		/// <summary>
		/// Utility function to load a paging control from the viewstate
		/// </summary>
		/// <param name="ViewState"></param>
		public void LoadFromViewstate( System.Web.UI.StateBag ViewState )
		{
			_startRow = (int) ViewState["StartRow"];
			_lastRow = (int) ViewState["LastRow"];
			_rowsPerPage = (int) ViewState["RowsPerPage"];
			_currentPage = (int) ViewState["CurrentPage"];
			_totalPages = (int) ViewState["TotalPages"];
			_totalRecords = (int) ViewState["TotalRecords"];
			_hasNextButton = (bool) ViewState["hasNextButton"];
			_hasPrevButton = (bool) ViewState["hasPrevButton"];
			_nextPageRowStart = (int) ViewState["nextPageRowStart"];
			_prevPageRowStart = (int) ViewState["prevPageRowStart"];
		}

	}
}
